function spaceToBuild()
	local ll = entity.toAbsolutePosition({ self.leftOffset, self.bottomOffset })
	local tr = entity.toAbsolutePosition({ self.rightOffset, self.topOffset })

	local bounds = {0, 0, 0, 0}
	bounds[1] = ll[1]
	bounds[2] = ll[2]
	bounds[3] = tr[1]
	bounds[4] = tr[2]

	local entityId = entity.id()
	local ents = world.entityQuery(ll, tr, {withoutEntityId = entityId})
	if ents then
		local count = 0
		for i, j in pairs(ents) do
			world.logInfo("Obstruction detected: " .. world.entityName(j))
			count = count + 1
		end
		if count > 0 then
			return false
		end
	end

	return not world.rectCollision(bounds, false)
end

function hooverUp()
	local ll = entity.toAbsolutePosition({ self.leftOffset - 1.0, self.bottomOffset - 1.0 })
	local tr = entity.toAbsolutePosition({ self.rightOffset + 1.0, self.topOffset + 1.0 })

	local bounds = {0, 0, 0, 0}
	bounds[1] = ll[1]
	bounds[2] = ll[2]
	bounds[3] = tr[1]
	bounds[4] = tr[2]

	local ents = world.itemDropQuery(ll, tr)
	local count = 0
	if ents then
		for i, j in pairs(ents) do
			count = count + 1
			world.takeItemDrop(j, entity.id())
		end
	end
	if count == 0 then
		return true
	end

	return false
end

function init(args)
	self.buildingStage = 0
	self.h = 8
	self.w = 17
	self.leftOffset = -9.0
	self.bottomOffset = 1.0
	self.rightOffset = 8.0
	self.topOffset = 8.0
	self.blueprintBackground = {}
	self.blueprintForeground = {}
	self.blueprintTrimBackground = {}
	self.objectNames = {}
	self.objectPos = {}
	self.optionalBlocks = function(x, y)
			world.placeMaterial({x - 2, y}, "foreground", "modernplatform")
			world.placeMaterial({x - 1, y + 1}, "foreground", "modernplatform")
			world.placeMaterial({x + 19, y}, "foreground", "modernplatform")
			world.placeMaterial({x + 18, y + 1}, "foreground", "modernplatform")
		end

	-- Set up background blueprint
	for y = 0, self.h, 1 do
		for x = 0, self.w, 1 do
			local pos = x .. "," .. y
			self.blueprintBackground[pos] = nil
		end
	end
	for y = 1, self.h, 1 do
		for x = 0, self.w, 1 do
			local pos = x .. "," .. y
			self.blueprintBackground[pos] = "pressurizedsteel"
		end
	end
	self.blueprintBackground["2,0"] = "apexshipsupport"
	self.blueprintBackground["3,0"] = "apexshipsupport"
	self.blueprintBackground["14,0"] = "apexshipsupport"
	self.blueprintBackground["15,0"] = "apexshipsupport"
	for y = 4, 6, 1 do
		for x = 3, 8, 1 do
			local pos = x .. "," .. y
			self.blueprintBackground[pos] = "glass"
		end
	end
	for y = 2, 6, 1 do
		for x = 0, self.w, self.w do
			local pos = x .. "," .. y
			self.blueprintBackground[pos] = nil
		end
	end

	-- Set up foreground blueprint
	for y = 0, self.h, 1 do
		for x = 0, self.w, 1 do
			local pos = x .. "," .. y
			self.blueprintForeground[pos] = nil
		end
	end
	for y = 1, self.h, 1 do
		for x = 0, self.w, 1 do
			local pos = x .. "," .. y
			self.blueprintForeground[pos] = "smoothmetal"
		end
	end
	for y = 2, 7, 1 do
		for x = 1, 16, 1 do
			local pos = x .. "," .. y
			self.blueprintForeground[pos] = nil
		end
	end
	for y = 2, 6, 1 do
		for x = 0, self.w, self.w do
			local pos = x .. "," .. y
			self.blueprintForeground[pos] = nil
		end
	end

	-- Set up area to be trimmed
	for y = 0, self.h, 1 do
		for x = 0, self.w, 1 do
			local pos = x .. "," .. y
			self.blueprintTrimBackground[pos] = false
		end
	end
	for x = 0, 1, 1 do self.blueprintTrimBackground[x .. ",0"] = true end
	for x = 4, 13, 1 do self.blueprintTrimBackground[x .. ",0"] = true end
	for x = 16, 17, 1 do self.blueprintTrimBackground[x .. ",0"] = true end

	-- Set up furniture list
	furnitureSetup()

	self.pos = {}
	self.pos = entity.toAbsolutePosition({self.leftOffset, 0.0})
end

function main()
	local pos = self.pos
	if self.buildingStage == 0 then
		if spaceToBuild() then
			for y = 1, self.h, 1 do
				for x = 0, self.w, 1 do
					local pos2 = {pos[1] + x, pos[2] + y}
					world.damageTiles({pos2}, "background", pos2, "explosive", 10000)
					hooverUp()
				end
			end
			self.buildingStage = 1
		end
	elseif self.buildingStage == 1 then
		for y = 0, self.h, 1 do
			for x = 0, self.w, 1 do
				local pos2 = {pos[1] + x, pos[2] + y}
				local index = x .. "," .. y
				if self.blueprintBackground[index] ~= nil then
					world.placeMaterial(pos2, "background", self.blueprintBackground[index])
				end
			end
		end
		local check = true
		for y = 1, self.h, 1 do
			for x = 0, self.w, 1 do
				local pos2 = {pos[1] + x, pos[2] + y}
				local index = x .. "," .. y
				if world.material(pos2, "background") ~= self.blueprintBackground[index] then
					check = false
				end
			end
		end
		if check == true then
			self.buildingStage = 2
		end
	elseif self.buildingStage == 2 then
		for y = 0, self.h, 1 do
			for x = 0, self.w, 1 do
				local pos2 = {pos[1] + x, pos[2] + y}
				local index = x .. "," .. y
				if self.blueprintForeground[index] ~= nil then
					world.placeMaterial(pos2, "foreground", self.blueprintForeground[index])
				end
			end
		end
		local check = true
		for y = 0, self.h, 1 do
			for x = 0, self.w, 1 do
				local pos2 = {pos[1] + x, pos[2] + y}
				local index = x .. "," .. y
				if world.material(pos2, "foreground") ~= self.blueprintForeground[index] then
					check = false
				end
			end
		end
		if check == true then
			self.optionalBlocks(pos[1], pos[2])
			self.buildingStage = 3
		end
	elseif self.buildingStage == 3 then
--[[		for y = 0, self.h, 1 do
			for x = 0, self.w, 1 do
				local index = x .. "," .. y
				if self.blueprintTrimBackground[index] == true then
					local pos2 = {pos[1] + x, pos[2] + y}
					world.damageTiles({pos2}, "background", pos2, "explosive", 10000)
				end
			end
		end
--]]
		self.buildingStage = 4
	elseif self.buildingStage == 4 then
		for i, j in pairs(self.objectPos) do
			local pos2 = {pos[1] + j[1], pos[2] + j[2]}
			world.placeObject(self.objectNames[i], pos2)
		end
		self.buildingStage = 5
	elseif self.buildingStage == 5 then
		if hooverUp() then
			entity.smash()
		end
	end
end

function hasCapability(capability)
	return false
end
